package com.health.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import net.sf.json.JSONArray;
import net.sf.json.JsonConfig;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.health.constant.Constants;
import com.health.exceptions.ValidatorException;
import com.health.exceptions.ValidatorLevelException;
import com.health.form.UserForm;
import com.health.model.LoginInfo;
import com.health.model.User;
import com.health.service.IUserService;
import com.health.util.DateJsonValueProcessor;
import com.health.util.SecureUtils;

public class UserAction extends ActionInterface
{
	// Log Object
	private final Log		log	= LogFactory.getLog(UserAction.class);
	// Spring inject it
	private IUserService	userService;
	// use static method
	private SecureUtils		secureUtils;

	/**
	 * execute method across the action String to choose which logic will be
	 */
	@SuppressWarnings("static-access")
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws IOException
	{
		if (log.isInfoEnabled())
		{
			log.info("-----------UserAction is EXECUTING!-----------");
		}
		response.setContentType("text/html");
		response.setCharacterEncoding("GBK");
		UserForm userForm = (UserForm) form;

		String msg = "";
		User user = new User();
		user = userForm.convertFormToModel(userForm);
		// BeanUtils.copyProperties(form, user);
		PrintWriter out = response.getWriter();
		String action = request.getParameter("action");
		String password = user.getPassword();
		if (null != password)
		{
			password = secureUtils.BASE64Encode(password);
			user.setPassword(password);
		}

		if (null != action && !"".equals(action) && action.equals("register"))
		{
			int status = Constants.STATUS_NORMAL;// 0:normal 1:forbidden
			int permission = Constants.PERMISSION_NORMAL;// 0:admin 1:normal
			int loginCount = 0;
			user.setStatus(status);// the initial value is 0
			user.setPermission(permission);// the initial value is 0
			user.setRegistertime(new java.sql.Date((new java.util.Date()).getTime()));// initial
																						// value
			user.setLoginCount(loginCount);
			try
			{
				userService.insert(user);
				msg = "{success:true}";
				out.write(msg);
			}
			catch (ValidatorLevelException e)
			{
				log.error(e);
				msg = "{success:false , errors:'validator level exception!'}";
				out.write(msg);

			}
			catch (ValidatorException e)
			{
				e.printStackTrace();
				msg = "{success:false , errors:'data invalid!'}";
				out.write(msg);
			}
			return null;
		}
		if (null != action && "login".equals(action))
		{

			Object retObj = userService.login(user);
			if (null != retObj && retObj instanceof User)
			{
				User retUser = (User) retObj;
				if (retUser.getPermission() == 0)
				{
					// if admin(0)
					msg = "{success:true , ret:'" + Constants.PERMISSION_ADMIN
							+ "'}";
				}
				else if (retUser.getPermission() == 1)
				{
					// if normal user(1)
					msg = "{success:true , ret:'" + Constants.PERMISSION_NORMAL
							+ "'}";
				}
				if (retUser.getLoginCount() != 0)
				{
					retUser.setLoginCount(0);
					userService.update(retUser);
				}
				response.getWriter().write(msg);
				log.info("login success : " + user.getEmail());
				user = userService.selectListAll(user).get(0);
				request.getSession().setAttribute(Constants.LOGININFO,
						new LoginInfo(user.getId(),
								user.getName(),
								user.getEmail(),
								user.getPermission(),
								user.getStatus()));
				return null;
			}
			else if (null != retObj && retObj instanceof String)
			{
				String retStr = (String) retObj;
				log.warn("user login error");
				if (retStr == Constants.EMAIL_NOT_FOUND)
				{
					msg = "{success:false , errors:'email not found'}";
				}
				else if (retStr == Constants.ACCOUNT_LOCKED)
				{
					msg = "{success:false , errors:'because of many times to login error!<br>account locked!<br>plz contact our servicer'}";
				}
				else if (retStr == Constants.PASSWORD_NOT_CORRECT)
				{
					msg = "{success:false , errors:'password incorrect'}";
					User u = new User();
					u.setEmail(user.getEmail());
					u = (User) userService.selectListAll(u).get(0);
					u.setLoginCount(u.getLoginCount() + 1);
					userService.update(u);
				}
				response.getWriter().write(msg);
			}
			out.close();
		}
		if (null != action && "selectListPage".equals(action))
		{
			List<User> userList = new ArrayList<User>();
			userList = userService.selectListPage(user);
			List<User> userListAll = userService.selectListAll(user);
			JSONArray jsonList = JSONArray.fromObject(userList, jsonConfig);
			String resText = "{data:" + jsonList.toString() + ",totalCount:"
					+ userListAll.size() + "}";
			out.write(resText);
			log.info("resultText : " + resText);
			return null;
		}
		if (null != action && "modifyStatus".equals(action))
		{

			// accept a String like "XXX'XXX'XXX'" split by ' ,then analysis
			// with String's method,put the, into a ArrayList
			String ids = request.getParameter("ids");
			// analysis
			String[] idsArr = ids.split("'");
			for (String id : idsArr)
			{
				user = userService.selectByPK(id);
				if (null == user)
				{
					continue;
				}
				if (user.getStatus() == Constants.STATUS_FORBIDDEN)
				{
					user.setStatus(Constants.STATUS_NORMAL);
				}
				else if (user.getStatus() == Constants.STATUS_NORMAL)
				{
					user.setStatus(Constants.STATUS_FORBIDDEN);
				}
				try
				{
					userService.update(user);
				}
				catch (Exception e)
				{
					log.error("--catch exception");
				}
			}

			return null;
		}
		if (null != action && "delete".equals(action))
		{
			// accept a String like "XXX'XXX'XXX'" split by ' ,then analysis
			// with String's method,put the, into a ArrayList
			String ids = request.getParameter("ids");
			// analysis
			String[] idsArr = ids.split("'");
			for (String id : idsArr)
			{
				user = userService.selectByPK(id);
				if (null == user)
				{
					continue;
				}
				if (user.getPermission() == Constants.PERMISSION_ADMIN)
				{
					LoginInfo info = (LoginInfo) request.getSession()
							.getAttribute(Constants.LOGININFO);
					log.warn(info.getEmail() + " is trying to delete "
							+ user.getEmail());
					continue;
				}
				else if (user.getPermission() == Constants.PERMISSION_NORMAL)
				{
					userService.delete(user);
				}
			}
			return null;
		}
		if (null != action && "logout".equals(action))
		{
			HttpSession session = request.getSession();
			session.removeAttribute(Constants.LOGININFO);
			return null;
		}
		return null;
	}

	/**
	 * getters and setters
	 */
	public IUserService getUserService()
	{
		return userService;
	}

	public void setUserService(IUserService userService)
	{
		this.userService = userService;
	}
}
